import tkinter as tk
from tkinter import messagebox, simpledialog
import os
import sys

# 配置
MAX_USER = 10
INPUT_FILE = "account_in.txt"
OUTPUT_FILE = "account_out.txt"

# 全局数据
users = []          # 所有用户列表
current_user = None # 当前登录用户
current_pos = -1    # 当前用户索引


class Account:
    def __init__(self, user_id, username, password, money):
        self.id = int(user_id)
        self.username = username.strip()
        self.password = password.strip()
        self.money = float(money)

    def __str__(self):
        return f"{self.id};{self.username};{self.password};{self.money:.2f}"


def init():
    """从文件加载用户数据"""
    global users
    if not os.path.exists(INPUT_FILE):
        messagebox.showerror("错误", f"找不到用户数据文件：{INPUT_FILE}")
        sys.exit(1)

    try:
        with open(INPUT_FILE, 'r', encoding='utf-8') as f:
            lines = f.readlines()

        users = []
        for line in lines:
            line = line.strip()
            if not line:
                continue
            parts = [p.strip() for p in line.split(';')]
            if len(parts) == 4:
                user = Account(parts[0], parts[1], parts[2], parts[3])
                if len(users) < MAX_USER:
                    users.append(user)
    except Exception as e:
        messagebox.showerror("加载失败", f"无法读取用户数据：{e}")
        sys.exit(1)


def save_info():
    """保存所有用户信息到文件"""
    try:
        with open(OUTPUT_FILE, 'w', encoding='utf-8') as f:
            for user in users:
                f.write(str(user) + '\n')
        messagebox.showinfo("保存成功", f"用户数据已保存到 {OUTPUT_FILE}")
    except Exception as e:
        messagebox.showerror("保存失败", f"无法保存数据：{e}")


def search_user_by_id(user_id, password):
    """查找用户，返回 (用户, 索引) 或 (None, -1)"""
    for i, u in enumerate(users):
        if u.id == int(user_id) and u.password == password:
            return u, i
    return None, -1


# ========================
# GUI 界面类
# ========================

class ATMApp:
    def __init__(self, root):
        self.root = root
        self.root.title("ATM 自动取款机系统")
        self.root.geometry("500x400")
        self.root.resizable(False, False)
        self.root.configure(bg="#f0f0f0")

        # 设置字体
        self.font_title = ("微软雅黑", 16, "bold")
        self.font_label = ("微软雅黑", 10)
        self.font_btn = ("微软雅黑", 10)

        self.show_login()

    def show_login(self):
        """显示登录界面"""
        self.clear_window()

        tk.Label(self.root, text="ATM 系统登录", font=self.font_title, bg="#f0f0f0").pack(pady=30)

        tk.Label(self.root, text="账户编号：", font=self.font_label, bg="#f0f0f0").pack()
        self.entry_id = tk.Entry(self.root, font=self.font_label, width=20)
        self.entry_id.pack(pady=5)

        tk.Label(self.root, text="密码：", font=self.font_label, bg="#f0f0f0").pack()
        self.entry_password = tk.Entry(self.root, font=self.font_label, width=20, show="*")
        self.entry_password.pack(pady=5)

        tk.Button(
            self.root, text="登录", font=self.font_btn, width=15,
            command=self.login, bg="#4CAF50", fg="white"
        ).pack(pady=20)

        # 绑定回车键登录
        self.root.bind('<Return>', lambda event: self.login())

    def login(self):
        """处理登录逻辑"""
        user_id = self.entry_id.get().strip()
        password = self.entry_password.get().strip()

        if not user_id or not password:
            messagebox.showwarning("警告", "请输入完整的账户信息！")
            return

        try:
            user_id = int(user_id)
        except:
            messagebox.showwarning("警告", "账户编号必须是数字！")
            return

        user, pos = search_user_by_id(user_id, password)
        if user:
            global current_user, current_pos
            current_user = user
            current_pos = pos
            messagebox.showinfo("登录成功", f"欢迎 {user.username}！")
            self.show_main_menu()
        else:
            messagebox.showerror("登录失败", "账户编号或密码错误！")

    def show_main_menu(self):
        """显示主菜单"""
        self.clear_window()

        tk.Label(self.root, text=f"欢迎使用 ATM 系统", font=self.font_title, bg="#f0f0f0").pack(pady=20)
        tk.Label(self.root, text=f"当前用户：{current_user.username} ({current_user.id})", 
                 font=("微软雅黑", 10), bg="#f0f0f0", fg="blue").pack()

        btn_frame = tk.Frame(self.root, bg="#f0f0f0")
        btn_frame.pack(pady=30)

        tk.Button(btn_frame, text="1. 查询余额", font=self.font_btn, width=15, height=2,
                  command=self.show_balance).grid(row=0, column=0, padx=10, pady=5)

        tk.Button(btn_frame, text="2. 取款", font=self.font_btn, width=15, height=2,
                  command=self.withdraw).grid(row=0, column=1, padx=10, pady=5)

        tk.Button(btn_frame, text="3. 修改密码", font=self.font_btn, width=15, height=2,
                  command=self.change_password).grid(row=1, column=0, padx=10, pady=5)

        tk.Button(btn_frame, text="4. 转账", font=self.font_btn, width=15, height=2,
                  command=self.transfer).grid(row=1, column=1, padx=10, pady=5)

        tk.Button(self.root, text="5. 退出系统", font=self.font_btn, width=20, height=2,
                  bg="#f44336", fg="white", command=self.exit_system).pack(pady=20)

    def show_balance(self):
        """显示余额"""
        messagebox.showinfo(
            "账户信息",
            f"用户姓名: {current_user.username}\n"
            f"账户余额: {current_user.money:.2f} 元"
        )

    def withdraw(self):
        """取款"""
        amount = simpledialog.askfloat("取款", "请输入取款金额：", minvalue=0.01)
        if amount is None:
            return
        if amount > current_user.money:
            messagebox.showwarning("余额不足", "您的账户余额不足！")
        else:
            current_user.money -= amount
            messagebox.showinfo("取款成功", f"已取出 {amount:.2f} 元\n余额：{current_user.money:.2f} 元")

    def change_password(self):
        """修改密码"""
        old_pass = simpledialog.askstring("修改密码", "请输入原密码：", show="*")
        if old_pass is None:
            return
        if old_pass != current_user.password:
            messagebox.showerror("错误", "原密码不正确！")
            return

        new_pass = simpledialog.askstring("修改密码", "请输入新密码：", show="*")
        if not new_pass:
            messagebox.showwarning("警告", "密码不能为空！")
            return

        confirm_pass = simpledialog.askstring("修改密码", "请再次输入新密码：", show="*")
        if new_pass != confirm_pass:
            messagebox.showerror("错误", "两次输入不一致！")
        else:
            current_user.password = new_pass
            messagebox.showinfo("成功", "密码修改成功！")

    def transfer(self):
        """转账"""
        target_id = simpledialog.askinteger("转账", "请输入对方账户编号：")
        if target_id is None:
            return
        if target_id == current_user.id:
            messagebox.showwarning("警告", "不能给自己转账！")
            return

        target_user = None
        for u in users:
            if u.id == target_id:
                target_user = u
                break

        if not target_user:
            messagebox.showerror("错误", "对方账户不存在！")
            return

        amount = simpledialog.askfloat("转账", f"当前余额：{current_user.money:.2f}\n转账给 {target_user.username} 的金额：", minvalue=0.01)
        if amount is None:
            return
        if amount > current_user.money:
            messagebox.showwarning("余额不足", "账户余额不足！")
        else:
            current_user.money -= amount
            target_user.money += amount
            messagebox.showinfo("转账成功", f"成功转账 {amount:.2f} 元给 {target_user.username}\n余额：{current_user.money:.2f} 元")

    def exit_system(self):
        """退出系统"""
        if messagebox.askyesno("确认退出", "是否保存数据并退出？"):
            self.sync_user()
            save_info()
            self.root.quit()

    def sync_user(self):
        """同步当前用户到 users 列表"""
        if current_user is not None and 0 <= current_pos < len(users):
            users[current_pos] = current_user

    def clear_window(self):
        """清空当前窗口所有组件"""
        for widget in self.root.winfo_children():
            widget.destroy()


# ========================
# 主程序入口
# ========================

def main():
    init()
    root = tk.Tk()
    app = ATMApp(root)
    root.mainloop()


if __name__ == "__main__":
    main()
